// 声明主包
package main

// 导入所需的包
import (
	"net/http" // 提供HTTP客户端和服务器的实现
	"time"     // 提供时间的测量和显示功能

	"github.com/gin-gonic/gin"  // Gin Web框架
	"github.com/golang-jwt/jwt" // JWT认证包
)

// JWT密钥，用于签名和验证JWT令牌
// 在生产环境中应该使用更安全的密钥，并通过环境变量或配置文件管理
var jwtSecret = []byte("your_secret_key")

// GenerateToken 为指定用户名创建JWT令牌
// 参数：
// - username: 用户名
// 返回：
// - string: 生成的JWT令牌字符串
// - error: 可能发生的错误
func GenerateToken(username string) (string, error) {
	// 创建一个新的JWT令牌，使用HS256签名方法
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
		"username": username,                             // 设置用户名声明
		"exp":      time.Now().Add(2 * time.Hour).Unix(), // 设置令牌过期时间为2小时后
	})
	// 使用密钥对令牌进行签名并返回签名后的字符串
	return token.SignedString(jwtSecret)
}

// JWTAuthMiddleware 创建一个JWT认证中间件
// 返回一个Gin处理函数，用于验证请求中的JWT令牌
func JWTAuthMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		// 从请求头中获取Authorization字段
		authHeader := c.GetHeader("Authorization")
		if authHeader == "" {
			// 如果没有Authorization头，返回401未授权错误
			c.JSON(http.StatusUnauthorized, gin.H{"error": "Authorization header required"})
			c.Abort() // 终止请求处理
			return
		}
		// 提取令牌字符串，去掉"Bearer "前缀
		tokenString := authHeader[len("Bearer "):]
		// 解析和验证令牌
		token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
			// 验证签名方法是否为HMAC
			if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
				return nil, jwt.ErrSignatureInvalid
			}
			return jwtSecret, nil
		})
		// 如果解析出错或令牌无效，返回401未授权错误
		if err != nil || !token.Valid {
			c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid or expired token"})
			c.Abort() // 终止请求处理
			return
		}
		// 令牌验证通过，继续处理请求
		c.Next()
	}
}

// main函数，应用程序的入口点
func main() {
	// 创建默认的Gin路由引擎
	r := gin.Default()

	// 定义登录路由，处理POST请求
	r.POST("/login", func(c *gin.Context) {
		// 定义登录数据结构，使用tag指定JSON字段名和验证规则
		var loginData struct {
			Username string `json:"username" binding:"required"` // 用户名字段，必填
			Password string `json:"password" binding:"required"` // 密码字段，必填
		}
		// 将请求体绑定到loginData结构体
		if err := c.ShouldBindJSON(&loginData); err != nil {
			// 如果绑定失败，返回400错误
			c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request"})
			return
		}
		// 这里可以添加验证用户名密码的逻辑
		// 生成JWT令牌
		token, err := GenerateToken(loginData.Username)
		if err != nil {
			// 如果生成令牌失败，返回500内部服务器错误
			c.JSON(http.StatusInternalServerError, gin.H{"error": "Could not generate token"})
			return
		}
		// 返回成功响应，包含生成的令牌
		c.JSON(http.StatusOK, gin.H{"token": token})
	})

	// 创建需要认证的API路由组
	auth := r.Group("/api")
	auth.Use(JWTAuthMiddleware()) // 应用JWT认证中间件
	{
		// 定义受保护的路由，只有验证通过的请求才能访问
		auth.GET("/protected", func(c *gin.Context) {
			c.JSON(http.StatusOK, gin.H{"message": "This is a protected route"})
		})
	}

	// 启动HTTP服务器，监听8080端口
	r.Run(":8080")
}
